package Meter::Config;

#===============================================================================
#     REVISION:  $Id: Config.pm 172 2013-02-26 10:19:53Z xdr.box@gmail.com $
#  DESCRIPTION:  Config access module
#===============================================================================

use strict;
use warnings;

use Readonly;
Readonly our $VERSION => qw($Revision: 172 $) [1];

use English qw( -no_match_vars );

#use Smart::Comments;

use Meter::Log;

Readonly my $DEFAULT_CONFIG => "$ENV{'METER_ROOT'}/conf/meter.conf";

use base qw(Exporter);

## no critic (ProhibitAutomaticExportation)
our @EXPORT = qw(
    get_config
);
## use critic

Readonly my $VALIDATOR => {
    session_life_time_minutes    => 1,
    session_cookie_expires       => 1,
    time_zone                    => 1,
    charset                      => 1,
    locale                       => 1,
    redirect_ok_delay_seconds    => 1,
    redirect_error_delay_seconds => 1,
    webapp_cgi                   => 1,
    site_url                     => 1,
    title                        => 1,
    contact_email                => 1,
    email                        => {
        disable          => 1,
        from_address     => 1,
        validity_checks  => { -mxcheck => 1, -tldcheck => 1, -fqdn => 1 },
        net_smtp_options => {
            Host    => 1,
            Port    => 1,
            Timeout => 1,
        },
    },
    notification_schedule => {
        start_day => 1,
        end_day   => 1,
    },
    idle_online_minutes_at_most => 1,
};

sub get_config {
    my $file_name = shift || $ENV{'METER_CONFIG'} || $DEFAULT_CONFIG;

    my $logger = get_logger();
    $logger->debug("Config file: $file_name");

    # Slurp and eval Perl-code from $file_name
    my $config = do $file_name;

    if ( !$config ) {

        # Cannot parse
        if ($EVAL_ERROR) {
            die "Cannot parse $file_name: $EVAL_ERROR\n";
        }

        # File not found or not accessible
        if ( !defined $config ) {
            die "Cannot read $file_name: $OS_ERROR\n";
        }

        # Last expression in $file_name was evaluated as false
        if ( !$config ) {
            die "Bad file format: $file_name\n";
        }
    }

    # Check that we've got an HASH ref
    if ( ref $config ne 'HASH' ) {
        die "Bad file format: $file_name - HASH ref was expected\n";
    }

    # Unfortunately, Debian Squeeze has no Data::Validate::Struct
    # module packaged yet. I don't want install module from CPAN
    # on hosted server.
    _validate_config( $config, $VALIDATOR );

    ### config: $config
    return $config;
}

sub _validate_config {
    my $config    = shift;
    my $validator = shift;

    while ( my ( $key, $value ) = each %{$validator} ) {
        if ( !exists $config->{$key} ) {
            die "Config has no '$key' parameter\n";
        }

        if ( ref $value eq 'HASH' ) {
            _validate_config( $config->{$key}, $value );
        }
    }

    return;
}

1;
